#include "waypointlist.h"
using namespace FsxSimConnect;

//
// JSON representation of all waypoints.
//
QString WaypointList::toJsonArray(const int level, const qint64 resolutionPeriodMs) const {

    // working on reduced list
    if (resolutionPeriodMs >= WPMINREDUCEDRESOLUTION) {
        WaypointList reducedWaypoints = WaypointList::reducedResolution(resolutionPeriodMs);
        return reducedWaypoints.toJsonArray(level, -1);
    }

    const QString ind = JsonMarkupHelper::Indention(level);
    const QString indp1 = JsonMarkupHelper::Indention(level+1);
    QString a = ind + "[\n";
    int c = WaypointList::count();
    for (int i =0; i < c; i++) {
        Waypoint w = WaypointList::at(i);
        a.append(w.toJson(level+1));
        a.append((i + 1 < c) ? indp1 + ",\n" : "");
    }
    a.append(ind + "]\n");
    return a;
}

//
// KML representation of all waypoints
//
QString WaypointList::toKml(const int level, const KmlParameter &parameter) const {

    // working on reduced list
    if (parameter.maxNumberWaypoints == 0) return ""; // shortcut
    bool reduceRes = parameter.waypointResolutionPeriodMs >= WPMINREDUCEDRESOLUTION;
    bool reduceMax = parameter.maxNumberWaypoints > 0;

    // any reduction? recursively call this method with reduced list
    if (reduceMax || reduceRes) {
        WaypointList reducedWaypoints = reduceRes ? WaypointList::reducedResolution(parameter.waypointResolutionPeriodMs) : WaypointList(*this);
        if (reduceMax) reducedWaypoints.reduce(parameter.maxNumberWaypoints);
        KmlParameter reducedParameter(parameter);
        reducedParameter.maxNumberWaypoints = -1; // no maxnumbers
        reducedParameter.waypointResolutionPeriodMs = -1; // no period
        return reducedWaypoints.toKml(level, reducedParameter);
    }

    // build KML
    QString a;
    int c = WaypointList::count();
    if (c == 0) return "";

    const QString pmIcon = "http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png";
    const QString pmStyleHigh = "pmPlaneHigh";
    const QString pmStyleNormal = "pmPlaneNormal";

    // a.append(WaypointList::at(0).toKmlLookAt(level+1));
    // a.append(WaypointList::toKmlLookAt(level, 5));
    a.append(JsonMarkupHelper::kmlNetworkLinkControl(level+1, parameter.networkLinkUpdatePeriodS*1000, WaypointList::toKmlLookAt(level+2, 5)));
    a.append(JsonMarkupHelper::kmlPlacemarkStyle(level+1, pmStyleHigh, pmIcon , 0.6, 0.6));
    a.append(JsonMarkupHelper::kmlPlacemarkStyle(level+1, pmStyleNormal, pmIcon, 0.5, 0.6));
    a.append(JsonMarkupHelper::kmlStyleMap(level + 1, "waypointExtended", pmStyleNormal, pmStyleHigh));

    for (int i =0; i < c; i++) {
        Waypoint w = WaypointList::at(i);
        bool withModel = i < 1 || w.hasPositionChanged(WaypointList::at(i-1));
        a.append(w.toKmlPlacemarks(level+1, true, withModel, parameter.modelUrl, parameter.waypointTitle, parameter.waypointFurtherInfo));
    }
    a.append(WaypointList::toKmlTrack(level+1));
    return JsonMarkupHelper::kmlWrapInDocument(level, a, "Waypoints");
}

//
// KML representation of the track
//
QString WaypointList::toKmlTrack(const int level) const {
    QString a;
    int c = WaypointList::count();
    if (c < 2) return "";

    const QString ind  = JsonMarkupHelper::Indention(level);
    const QString ind1 = JsonMarkupHelper::Indention(level+1);
    const QString ind2 = JsonMarkupHelper::Indention(level+2);

    a.append(ind  + "<Placemark>\n");
    a.append(ind1 + "<name>" + QString::number(c) + " waypoints</name>\n");
    a.append(ind1 + "<LineString>\n");
    a.append(ind2 + "<extrude>1</extrude>\n");
    a.append(ind2 + JsonMarkupHelper::KmlAltModeAbsolute + "\n");
    a.append(ind2 + "<tessellate>1</tessellate>\n");
    a.append(ind2 + "<coordinates>\n");
    for (int i =0; i < c; i++) {
        Waypoint w = WaypointList::at(i);
        a.append(ind2 + QString::number(w.getLongitudeDeg(),'f',WPLATLNGPREC) + "," +
                 QString::number(w.getLatitudeDeg(),'f',WPLATLNGPREC) + "," +
                 QString::number(w.getAltitudeM()) + "\n" );
    }
    a.append(ind2 + "</coordinates>\n");
    a.append(ind1 + "</LineString>\n");
    a.append(ind1 + "<Style>\n");
    a.append(JsonMarkupHelper::kmlLineStyle(level+2));
    a.append(JsonMarkupHelper::kmlPolyStyle(level+2));
    a.append(ind1 + "</Style>\n");
    a.append(ind  + "</Placemark>\n");
    return a;
}

//
// Look at, based on last average waypoints
//
QString WaypointList::toKmlLookAt(const int level, const int lastWaypoints) const {
    int ac;
    Waypoint average = WaypointList::average(lastWaypoints, ac);
    if (ac <1) return "";
    average.setAltitudeFt(average.getAltitudeFt() + 200);
    average.setHeadingTrueDeg(average.getHeadingTrueDeg()+30);
    average.setPitchDeg(90);
    return average.toKmlLookAt(level);
}
